#include "Param.hpp"
#include "TextHandlerManager.hpp"
#include "KeyfileTextHandler.hpp"
#include "KeyfileIncIndex.hpp"
#include "FlatFileClusterDB.hpp"
#include "KeyfileClusterDB.hpp"
#include "ClusterParam.hpp"


#include "IndexManager.hpp"

using namespace std;
using namespace lemur::api;

namespace LocalParameter {
	// name (minus extension) of the index
	string index;
	// type of index to build
	string indexType;
	// format of documents (trec or web)
	string docFormat;
	// whether or not to stem
	string stemmer;

	void get() {
		index = ParamGetString("index");
		indexType = ParamGetString("indexType");
		docFormat = ParamGetString("docFormat");
		stemmer = ParamGetString("stemmer");
	}
};

void GetAppParam()
{
	LocalParameter::get();
	ClusterParam::get();
}

int AppMain(int argc, char * argv[]) 
{
	Parser* parser = NULL;
	parser = TextHandlerManager::createParser(LocalParameter::docFormat);

	Stemmer* stemmer = NULL;
	stemmer = TextHandlerManager::createStemmer(LocalParameter::stemmer);

	lemur::index::KeyfileIncIndex* index = NULL;
	index = new lemur::index::KeyfileIncIndex(LocalParameter::index);

	TextHandler* indexer = NULL;	
	indexer = new lemur::parse::KeyfileTextHandler(index);


	TextHandler * th = parser;

	th->setTextHandler(stemmer);
	th = stemmer;

	th->setTextHandler(indexer);
	
	ClusterDB* clusterDB;
	clusterDB = new lemur::cluster::KeyfileClusterDB(index, 
                                     ClusterParam::clusterIndex,
                                     ClusterParam::threshold,
                                     ClusterParam::simType,
                                     ClusterParam::clusterType,
                                     ClusterParam::docMode);

	// parse and index files
	for (int i = 2; i < argc; i++) 
	{
		cerr << "Parsing file: " << argv[i] << endl;
		string filename(argv[i]);
		try {
			parser->parse(filename);
		} catch (Exception &ex) {
			LEMUR_RETHROW(ex, "Could not parse file");
		}
	}
	
	// cluster files 
	double score;
	for (DOCID_T i = 1; i <= index->docCount(); i++) 
	{
		if (clusterDB->getDocClusterId(i).size() == 0) 
		{
			// Hasn't been clustered yet.
			int myCluster = clusterDB->cluster(i, score);
			cout << index->document(i) << " " << myCluster << " " 
				<< score << endl;
		}
	}

	// index stats

	cout << endl << "Index" << endl;
	cout << "unique words: " << index->termCountUnique() << endl;	
	cout << "total words: " << index->termCount() << endl;	
	cout << "documents: " << index->docCount() << endl;
	
	
	// for (int termID = 1; termID <= index->termCountUnique(); termID++) 
	// {
	// 	cout << "id: " << termID << " term: " << index->term(termID) << endl;
	// }
	
	// clusterIndex stats
	cout << endl << "Cluster index" << endl;
	clusterDB->printClusters();

	// free memory
	delete clusterDB;
	delete indexer;
	delete stemmer;
	delete parser;
	delete index;
	
	return 0;
}

